package org.dromara.device.dubbo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.device.api.RemoteDeviceService;
import org.dromara.device.api.domain.vo.ApiDeviceVo;
import org.dromara.device.api.domain.vo.DeviceNameVo;
import org.dromara.device.api.domain.vo.OrdinaryDeviceVo;
import org.dromara.device.domain.DeviceConfig;
import org.dromara.device.domain.bo.DeviceConfigBo;
import org.dromara.device.domain.vo.DeviceConfigVo;
import org.dromara.device.service.IDeviceConfigService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@DubboService
@RequiredArgsConstructor
public class RemoteDeviceServiceImpl implements RemoteDeviceService {

    private final IDeviceConfigService deviceConfigService;

    @Override
    public List<ApiDeviceVo> queryAllList() {
        List<DeviceConfigVo> vos = TenantHelper.ignore(() -> deviceConfigService.queryList(new DeviceConfigBo()));
        return BeanUtil.copyToList(vos, ApiDeviceVo.class);
    }

    @Override
    public void updateBatchStatusByDeviceSn(List<ApiDeviceVo> deviceList) {
        TenantHelper.ignore(() -> {
            List<DeviceConfig> list = BeanUtil.copyToList(deviceList, DeviceConfig.class);
            deviceConfigService.updateBatchStatusByDeviceSn(list);
        });
    }

    @Override
    public ApiDeviceVo queryByDeviceSn(String deviceSn) {
        if (StrUtil.isBlank(deviceSn)) {
            throw new ServiceException("缺少必要的入参设备号");
        }
        DeviceConfigVo deviceConfigVo = TenantHelper.ignore(() -> {
            String[] deviceSns = {deviceSn};
            List<DeviceConfigVo> vos = deviceConfigService.selectOnlineByDeviceSnList(deviceSns);
            if (CollUtil.isEmpty(vos)) {
                return null;
            }
            return vos.get(0);
        });
        return ObjUtil.isNull(deviceConfigVo) ? null : BeanUtil.toBean(deviceConfigVo, ApiDeviceVo.class);
    }

    @Override
    public List<ApiDeviceVo> queryByDeviceIds(List<Long> deviceIds) {
        List<DeviceConfigVo> deviceConfigVos = getDeviceConfigVos(deviceIds);
        return ObjUtil.isNull(deviceConfigVos) ? null : BeanUtil.copyToList(deviceConfigVos, ApiDeviceVo.class);
    }

    @Override
    public Map<Long, String> queryNameByDeviceIds(List<Long> deviceIds) {
        if (CollUtil.isEmpty(deviceIds)) {
            return MapUtil.newHashMap();
        }
        List<DeviceConfigVo> deviceConfigVos = getDeviceConfigVos(deviceIds);
        if (CollUtil.isEmpty(deviceConfigVos)) {
            return MapUtil.newHashMap();
        }
        List<DeviceNameVo> deviceNameVos = BeanUtil.copyToList(deviceConfigVos, DeviceNameVo.class);
        return StreamUtils.toMap(deviceNameVos, DeviceNameVo::getDeviceId, DeviceNameVo::getName);
    }

    private List<DeviceConfigVo> getDeviceConfigVos(List<Long> deviceIds) {
        if (CollUtil.isEmpty(deviceIds)) {
            throw new ServiceException("缺少必要的入参设备id");
        }
        return TenantHelper.ignore(() -> {
            List<DeviceConfigVo> vos = deviceConfigService.selectByDeviceIds(deviceIds);
            if (CollUtil.isEmpty(vos)) {
                return null;
            }
            return vos;
        });
    }

    @Override
    public List<OrdinaryDeviceVo> queryByStoreIds(List<Long> storeIds) {
        if (CollUtil.isEmpty(storeIds)) {
            return CollUtil.newArrayList();
        }
        return deviceConfigService.queryByStoreIds(storeIds);
    }

    @Override
    public List<ApiDeviceVo> queryByNotStoreId() {
        List<DeviceConfigVo> vos = TenantHelper.ignore(deviceConfigService::selectByNotStoreId);
        return BeanUtil.copyToList(vos, ApiDeviceVo.class);
    }

    @Override
    public boolean unbindByStoreId(Long storeId) {
        return deviceConfigService.unbindByStoreId(storeId);
    }
}
